/*
 * Main.java
 *
 */

/**
 *
 * @author Osvaldo Rosado
 * @author Maybe you! Contribute changes.
 */
import java.awt.*;
import java.io.File;
import java.net.URL;
import java.util.Observable;
import java.util.Observer;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
import sun.awt.windows.WComponentPeer;

public class Main extends java.applet.Applet implements Observer {
    private Download selectedDownload;
    public static boolean ReadyClick = true;
    public static String StorageDir = System.getProperty("java.io.tmpdir") + "AppEmbed\\";
    Execute execute = new Execute();
    GetHWND GetHWND = new GetHWND();
    Embed Embed = new Embed();
    WinApi WinApi = new WinApi();
    public static boolean GMCHECK = false;
    public static boolean INSANITY = false;
    public static boolean INTERNALDOWNLOAD = false;
    public static String  CUSTOMCLASS = "";
    public static String  ARGUMENTS = "";
    int AppHwnd=0;

    @Override
    public  void init() {

             try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                java.awt.EventQueue.invokeAndWait(new Runnable() {
                    public void run() {
                        initComponents();
                        //Get Parameter Values
                        if(getParameter("GM")!=null){
                            if(getParameter("GM").equals("TRUE")){
                                GMCHECK=true;
                            }
                        }
                        if(getParameter("INSANITY")!=null){
                            if(getParameter("INSANITY").equals("TRUE")){
                                INSANITY=true;
                            }
                        }
                        if(getParameter("ClassID")!=null){
                            CUSTOMCLASS=getParameter("ClassID");
                        }
                        if(getParameter("Args")!=null){
                            ARGUMENTS=getParameter("Args");
                        }
                        //Set up UI
                        String appname=getParameter("name");
                        jLabel3.setText(appname+" would like to run");
                        jLabel4.setText(" r"+(Integer.parseInt(BuildInfo.revisionNumber)+1));//Make up for ant being run before commit.
                        //Most of the code relies on if the file download is complete.
                        //update() is where all the good stuff is at.
                        

                    }
                });
            } catch (Exception ex) {
                ex.printStackTrace();
            }
    }
    @Override
    public void destroy(){
        if(AppHwnd!=0){
            //Close the application
            int success = WinApi.User32.PostMessageA(AppHwnd,  0x0010, 0, 0);
            System.err.println(success);
            if (success!=1){
               System.err.println("Error terminating application.");
            }
        }
    }

public static long getAppletHandle(Panel f) {   return f.getPeer() != null ? ((WComponentPeer) f.getPeer()).getHWnd() : 0;}
//FIXME: Get rid of that ugly+unsupported way of getting HWND

private URL verifyUrl(String url) {
        // Only allow HTTP URLs.
        if (!url.toLowerCase().startsWith("http://"))
            return null;
        if(!url.toLowerCase().endsWith(".zip")){
            return null; 
        }
            
        // Verify format of URL.
        URL verifiedUrl = null;
        try {
            verifiedUrl = new URL(url);
        } catch (Exception e) {
            return null;
        }

        // Make sure URL specifies a file.
        if (verifiedUrl.getFile().length() < 2)
            return null;

        return verifiedUrl;
    }

public void update(Observable o, Object arg) {
    if(INTERNALDOWNLOAD==true){
        //Downloading internally needed files, dont try launching...
        jProgressBar1.setValue((int)selectedDownload.getProgress());
        jButton1.setText("Please Wait...");
        if((int)selectedDownload.getStatus()==2){
            System.err.println("Internal Download Complete");
            INTERNALDOWNLOAD=false; //All done!
            ReadyClick=true;
            jButton1.setEnabled(true);
            jButton1.doClick();
        }
    }else{
        jProgressBar1.setValue((int)selectedDownload.getProgress());
        if((int)selectedDownload.getStatus()==2){//Download Complete
            jButton1.setText("Extracting Files");
            Zip.Extract(selectedDownload.filestor());//Extract from zip
            jButton1.setText("Running...");
            String game=Execute.Findexe(StorageDir+Zip.getFileName(selectedDownload.filestor()));//Locate Exe to Execute
            System.err.println("Executing: "+game);
            String processpid=execute.Execute(game,StorageDir+Zip.getFileName(selectedDownload.filestor()),ARGUMENTS);
            if(processpid!=null){
                System.err.println("Result from AppLauncher: "+processpid);
                if(processpid.equals("")){
                    //Missing VS 2008 Libraries
                    JOptionPane.showMessageDialog(this,"You are missing the Visual Studio 2008 libraries.\nPlease install them from: http://bit.ly/MkvMb", "Error",JOptionPane.ERROR_MESSAGE);
                    jButton1.setText("Start");
                    jProgressBar1.setValue(0);
                    ReadyClick=true;
                    jButton1.setEnabled(true);
                }else{
                //Prepare to Embed
                if(panel1.isLightweight()==false)
                {
                       if(true == true)//Debug switch. Turns off embedding.
                       {
                           long AppletHwnd=getAppletHandle(panel1);
                           System.err.println("Applet HWND: "+AppletHwnd);
                           AppHwnd=GetHWND.GetHWND(processpid);
                           System.err.println("Application Frame HWND: "+AppHwnd);
                           //Embed Application
                           Embed.Embed(AppHwnd,(int)AppletHwnd);
                       }else{System.err.println("Fatal Error:Embedding Disabled");}

                    }else{System.err.println("Fatal Error:Not Lightweight");}
                    //Reset button, in case program exits.
                    jButton1.setText("Start");
                    jProgressBar1.setValue(0);
                    ReadyClick=true;
                    jButton1.setEnabled(true);
                }
            }else{
                System.err.println("Error. Could not execute.");
                JOptionPane.showMessageDialog(this,
                    "There was a problem running the program.", "Error",
                    JOptionPane.ERROR_MESSAGE);
                jButton1.setText("Launch Game");
                jProgressBar1.setValue(0);
                ReadyClick=true;
                jButton1.setEnabled(true);
            }
        }
    }
}

    /** This method is called from within the init() method to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        panel1 = new java.awt.Panel();
        jLabel1 = new javax.swing.JLabel();
        jPanel1 = new javax.swing.JPanel();
        jLabel3 = new javax.swing.JLabel();
        jButton1 = new javax.swing.JButton();
        jProgressBar1 = new javax.swing.JProgressBar();
        jPanel2 = new javax.swing.JPanel();
        jLabel4 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();

        setLayout(new java.awt.BorderLayout());

        panel1.setBackground(new java.awt.Color(204, 204, 204));
        panel1.setLayout(new java.awt.BorderLayout());

        jLabel1.setFont(new java.awt.Font("Tahoma", 0, 36));
        jLabel1.setText("AppEmbed");
        panel1.add(jLabel1, java.awt.BorderLayout.NORTH);

        jPanel1.setBackground(new java.awt.Color(204, 204, 204));
        jPanel1.setLayout(new java.awt.GridBagLayout());

        jLabel3.setText("ApplicationName would like to run");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.insets = new java.awt.Insets(7, 0, 7, 0);
        jPanel1.add(jLabel3, gridBagConstraints);

        jButton1.setText("Start");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        jPanel1.add(jButton1, gridBagConstraints);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.ipady = 6;
        gridBagConstraints.insets = new java.awt.Insets(13, 0, 13, 0);
        jPanel1.add(jProgressBar1, gridBagConstraints);

        panel1.add(jPanel1, java.awt.BorderLayout.CENTER);

        jPanel2.setBackground(new java.awt.Color(204, 204, 204));
        jPanel2.setLayout(new java.awt.GridLayout());

        jLabel4.setText("Version: 1.x");
        jPanel2.add(jLabel4);

        jLabel2.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        jLabel2.setText("http://code.google.com/p/appembed/");
        jPanel2.add(jLabel2);

        panel1.add(jPanel2, java.awt.BorderLayout.SOUTH);

        add(panel1, java.awt.BorderLayout.CENTER);
    }// </editor-fold>//GEN-END:initComponents

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        String geturl=getParameter("file");
        if (ReadyClick==true){
                ReadyClick=false;
                jButton1.setEnabled(false);
                //Check if we have the AppLauncher
                if(!new File(System.getProperty("java.io.tmpdir") + "AppEmbed\\"+"AppLauncher.exe").exists()){
                    //We need to download AppLauncher
                    //We can get it from Google Code
                    INTERNALDOWNLOAD=true;
                    URL AppLauncherURL;
                    try {
                        AppLauncherURL = new URL("http://appembed.googlecode.com/files/AppLauncher.exe");
                    } catch (Exception e) {
                        //This should never happen...
                        AppLauncherURL = null;
                    }
                    selectedDownload=new Download(AppLauncherURL);
                    selectedDownload.addObserver(this);
                    System.err.println("Handling Internal Download...");
                }else{
                    jButton1.setText("Loading...");
                    System.err.println("Attempting to download: "+geturl);
                    URL verifiedUrl = verifyUrl(geturl);
                    if (verifiedUrl != null) {
                        System.err.println("Downloading from: "+geturl);
                        selectedDownload=new Download(verifiedUrl);
                        selectedDownload.addObserver(this);
                    } else {
                        System.err.println("URL Not Valid: "+geturl);
                        JOptionPane.showMessageDialog(this,
                                "Invalid Download URL", "Error",
                                JOptionPane.ERROR_MESSAGE);
                    }
                }
            }
    }//GEN-LAST:event_jButton1ActionPerformed


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButton1;
    public javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JProgressBar jProgressBar1;
    public static java.awt.Panel panel1;
    // End of variables declaration//GEN-END:variables

}
